import json

from re_common.baselibrary.tools.all_requests.aiohttp_request import AioHttpRequest
from re_common.baselibrary.tools.all_requests.mrequest import MRequest

from apps.core.global_model import InputPlatformModel
from apps.crawler_platform.core_api.models import SaveMongoModel, SelectMongoModel, ResetMongoModel
from apps.crawler_platform.core_platform.core_g import IsHasEnum
from settings import URLDISTRIBUTED


class NoSqlUtil(object):

    @classmethod
    def set_is_his(cls, pm, is_his: str):
        """
        判断本次下载是否完成，如果完成，将在mongo表中当作一次历史记录
        is_his: True or False
        :return:
        """
        pm.set_is_his(is_his)

    @classmethod
    def set_save_para(cls, pm):
        """
        通用保存模型
        """
        return InputPlatformModel(
            data=SaveMongoModel(
                id=pm.Id,
                table=pm.one_para.task_set.nosql_table,
                is_his=str(pm.get_is_his(state=IsHasEnum.LATEST)),
                his_cnt=pm.one_para.task_set.history_cnt,
                para=pm.para,
                data=pm.down_model.dict()
            )).json()

    @classmethod
    def set_select_para(cls, pm):
        """
        通用获取模型
        """
        id_ = "_".join([pm.para[tmp] for tmp in pm.one_para.task_set.get_id_list()])
        # 查询mongoapi需要的请求参数结构
        data = InputPlatformModel(
            data=SelectMongoModel(
                # 只查询 new_data； {"new_data": 1} 属于mongo语法
                field={"new_data": 1},
                table=pm.one_para.task_set.nosql_table,
                and_param={"_id": id_},
            )).json()
        return data

    @classmethod
    def set_reset_new_data(cls, pm):
        """
        通用获取模型
        """
        id_ = "_".join([pm.para[tmp] for tmp in pm.one_para.task_set.get_id_list()])
        # 查询mongoapi需要的请求参数结构
        data = InputPlatformModel(
            data=ResetMongoModel(
                id=id_,
                table=pm.one_para.task_set.nosql_table,
            )).json()
        return data

    @classmethod
    async def save_nosql_html(cls, pm):
        """
        请求保存api
        :param pm:
        :return:
        """
        data = cls.set_save_para(pm)
        url = await URLDISTRIBUTED.get_mongo_save_url()
        rrq = AioHttpRequest()
        rrq.set_url(url) \
            .set_timeout(30) \
            .set_data(data) \
            .set_middler_list(
            [rrq.is_null_html_middlerwares, rrq.status_code_middlerwares])
        bools, dicts = await rrq.run(MRequest.POST)
        return bools, dicts

    @classmethod
    async def read_nosql_html(cls, pm):
        """
        按条件查询nosql数据库
        """
        # 期刊列表级默认保存历史
        data = cls.set_select_para(pm)
        url = await URLDISTRIBUTED.get_select_url()
        rrq = AioHttpRequest()
        rrq.set_url(url) \
            .set_timeout(30) \
            .set_data(data) \
            .set_middler_list(
            [rrq.is_null_html_middlerwares, rrq.status_code_middlerwares])
        bools, dicts = await rrq.run(MRequest.POST)
        if bools:
            pm.mongo_html = json.loads(rrq.html)
        return bools, dicts

    @classmethod
    async def reset_new_data(cls, pm):
        """
        按条件查询nosql数据库
        """
        # 期刊列表级默认保存历史
        data = cls.set_reset_new_data(pm)
        url = await URLDISTRIBUTED.get_reset_new_data_url()
        rrq = AioHttpRequest()
        rrq.set_url(url) \
            .set_timeout(30) \
            .set_data(data) \
            .set_middler_list(
            [rrq.is_null_html_middlerwares, rrq.status_code_middlerwares])
        bools, dicts = await rrq.run(MRequest.POST)
        return bools, dicts
